package com.jiwei.community.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jiwei.community.constants.SystemConstant;
import com.jiwei.community.dao.CollectionMapper;
import com.jiwei.community.dao.PostMapper;
import com.jiwei.community.entity.Collection;
import com.jiwei.community.entity.Like;
import com.jiwei.community.entity.Post;
import com.jiwei.community.enums.AppHttpCodeEnum;
import com.jiwei.community.exception.SystemException;
import com.jiwei.community.service.CollectionService;
import com.jiwei.community.utils.RedisCache;
import com.jiwei.community.vo.CollectionVo;
import com.jiwei.community.vo.PageListVo;
import com.jiwei.community.vo.ResponseResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * (Collection)表服务实现类
 *
 * @author jiwei
 * @since 2024-03-20 11:00:02
 */
@Service("collectionService")
public class CollectionServiceImpl extends ServiceImpl<CollectionMapper, Collection> implements CollectionService {
    @Resource
    CollectionMapper collectionMapper;
    @Resource
    PostMapper postMapper;
    @Autowired
    RedisCache redisCache;
    @Autowired
    RedisTemplate redisTemplate;
    @Override
    public ResponseResult collectPost(Long postId,Long userId) {
        Post post = postMapper.selectOne(new LambdaQueryWrapper<Post>().eq(Post::getId,postId));
        if (post==null)throw new SystemException(AppHttpCodeEnum.FAILURE,"帖子不存在");
        if (post.getCreateBy().equals(userId))throw new SystemException(AppHttpCodeEnum.FAILURE,"不能收藏自己的帖子");
        Collection collection = new Collection();
        collection.setPostId(postId);
        collection.setCreateBy(userId);
        boolean isOk = false;
        try{
            isOk = save(collection);
        }catch (DuplicateKeyException e){
            return ResponseResult.errorResult(AppHttpCodeEnum.FAILURE,"已收藏，不可重复收藏");
        }
        updateCollectNum(post,isOk?1:0);
        updateScoreByCollect(userId,postId,1);
        return ResponseResult.okResult("收藏成功");
    }

    @Override
    public ResponseResult cancelCollect(Long postId, Long userId) {
        Post post = postMapper.selectOne(new LambdaQueryWrapper<Post>().eq(Post::getId,postId));
        if (post==null)throw new SystemException(AppHttpCodeEnum.FAILURE,"帖子不存在");
        boolean isOk = remove(new LambdaQueryWrapper<Collection>().eq(Collection::getCreateBy,userId).eq(Collection::getPostId,postId));

        if (isOk){
            updateCollectNum(post,-1);
            updateScoreByCollect(userId,postId,-1);
            return ResponseResult.okResult("取消成功");
        }else {
            return ResponseResult.errorResult(AppHttpCodeEnum.FAILURE,"取消失败");
        }
    }

    public void updateCollectNum(Post post, Integer increase){
        Integer likedNum = redisCache.getCacheMapValue("post:collect-num",post.getId()+"");
        if (likedNum == null){

            likedNum = post.getLikedNum();
        }
        likedNum+=increase;
        updateRedisCollectNumAsync(post.getId(),likedNum);
    }
    @Async("redisStatisticsExecutor")
    void updateRedisCollectNumAsync(Long postId, Integer increase){
        redisCache.setCacheMapValue("post:collect-num",postId+"",increase);
    }

    @Override
    public ResponseResult getCollectionList(Integer pageNum, Integer pageSize,Long userId) {
        Page< CollectionVo> page = new Page<>();
        collectionMapper.getCollectionList(page,userId);
        PageListVo<CollectionVo> pageListVo = new PageListVo<>(page.getTotal(),page.getRecords());
        return ResponseResult.okResult(pageListVo);
    }

    @Override
    public ResponseResult isCollected(Long userId, Long postId) {
        LambdaQueryWrapper<Collection> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Collection::getCreateBy,userId);
        queryWrapper.eq(Collection::getPostId,postId);
        int count = count(queryWrapper);
        Map map = new HashMap();
        map.put("isCollected",count>0);
        return ResponseResult.okResult(map);
    }

    public void updateScoreByCollect(Long userId, Long postId, Integer increase) {
        redisTemplate.opsForZSet().incrementScore(SystemConstant.REDIS_PREFIX_RECOMMEND_SCORE+userId,postId,SystemConstant.RECOMMEND_SCORE_FACTOR_COLLECT*increase);

    }
}

